package flare.animate.interpolate
{
  import flare.util.Arrays;

  /**
   * Interpolator for numeric <code>Array</code> values. Each value
   * contained in the array should be a numeric (<code>Number</code> or
   * <code>int</code>) value.
   */
  public class ArrayInterpolator extends Interpolator
  {
    private var _start:Array;
    private var _end:Array;
    private var _cur:Array;

    /**
     * Creates a new ArrayInterpolator.
     * @param target the object whose property is being interpolated
     * @param property the property to interpolate
     * @param start the starting array of values to interpolate from
     * @param end the target array to interpolate to. This should be an
     *  array of numerical values.
     */
    public function ArrayInterpolator(target:Object, property:String, start:Object, end:Object)
    {
      super(target, property, start, end);
    }

    /**
     * Initializes this interpolator.
     * @param start the starting value of the interpolation
     * @param end the target value of the interpolation
     */
    protected override function init(start:Object, end:Object):void
    {
      _end = end as Array;

      if(!end)throw new Error("Target array is null!");

      if(_start && _start.length != _end.length)_start = null;
      _start = Arrays.copy(start as Array, _start);

      if(_start.length != _end.length)
      throw new Error("Array dimensions don't match");

      var cur:Array = _prop.getValue(_target) as Array;

      if(cur == end)cur = null;
      _cur = Arrays.copy(_start, cur);
    }

    /**
     * Calculate and set an interpolated property value.
     * @param f the interpolation fraction (typically between 0 and 1)
     */
    public override function interpolate(f:Number):void
    {
      for(var i:uint = 0; i < _cur.length; ++i)
      {
        _cur[i] = _start[i] + f * (_end[i] - _start[i]);
      }
      _prop.setValue(_target, _cur);
    }
  } // end of class ArrayInterpolator
}